﻿using Aspfm.Main;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Transactions;
using System.IO;
namespace Aspfm.Html
{
    public class AspfmWeb : Aspfm.Main.IMainController
    {
        public override void MvcController(string active)
        {
            if (active == "querysql")
            {
                string absolutepath = GetLocalPath();
                string sign = RequestDynObj.GetPropertyValueStr("fmparams.execsign");
                object pagesize = RequestDynObj.GetPropertyValue("fmparams.pagesize");
                object pageindex = RequestDynObj.GetPropertyValue("fmparams.pageindex");
                if(!string.IsNullOrEmpty(sign) && pagesize !=null && pageindex!=null)
                {
                    List<WebResult> webresult = QuerySql(sign.ToString(), absolutepath, Convert
                        .ToInt32(pageindex),Convert.ToInt32(pagesize),RequestDynObj,0);
                   base.ReturnObj(webresult);
                }
            }
            else if (active == "pksequence")
            {
                string sequencename = RequestDynObj.GetPropertyValueStr("fmparams.sequencename");
                string connkey = RequestDynObj.GetPropertyValueStr("fmparams.connkey");
                Aspfm.Dal.IDbHelper idb = Aspfm.Dal.DbFactory.GetDB(connkey);
                WebResult bwr = new WebResult();
                bwr.WebDataSet = WebDataTable.DataSetToWeb(idb.QuerySql("select " + sequencename + ".nextval PK from dual"));
                base.ReturnObj(bwr);
            }
            else if (active == "getpkorderid")
            {
                string connkey = RequestDynObj.GetPropertyValueStr("fmparams.connkey");
                string beforeStr = RequestDynObj.GetPropertyValueStr("fmparams.beforeStr");
                string LASTPKID = RequestDynObj.GetPropertyValueStr("fmparams.LASTPKID");
                string lengthstr = RequestDynObj.GetPropertyValueStr("fmparams.length");
                Aspfm.Dal.IDbHelper idb = Aspfm.Dal.DbFactory.GetDB(connkey);
                WebResult bwr = new WebResult();
                decimal length = 0;
                decimal.TryParse(lengthstr, out length);
                decimal maxid = idb.GetPkOrderId(beforeStr, LASTPKID);
                string maxidstr = "";
                if (length > 0 && maxid.ToString().Length < length)
                {
                    for (int i = 0; i < length - maxid.ToString().Length; i++)
                    {
                        maxidstr += "0";
                    }
                }
                bwr.Result.SetPropertyValue("PkOrderId", maxidstr + maxid.ToString());
                base.ReturnObj(bwr);
            }
            else if (active == "WriteLogSql".ToLower())
            {
                string logobjid = RequestDynObj.GetPropertyValueStr("fmparams.logobjid");
                string logmsg = RequestDynObj.GetPropertyValueStr("fmparams.logmsg");
                Aspfm.Dal.DbFactory.WriteLog(logmsg, logobjid, true);
            }
            else if (active == "websave".ToLower())
            {
                string absolutepath = GetLocalPath();
                string sign = RequestDynObj.GetPropertyValueStr("fmparams");
                if (!string.IsNullOrEmpty(sign))
                {
                    List<WebResult> webresult = UpdateSql(sign, absolutepath, RequestDynObj);
                    base.ReturnObj(webresult);
                }
            }
        }

        [Description("获取数据")]
        public static List<WebResult> QuerySql(string sign, string AbsolutePath, decimal pageindex, decimal pagesize, AspfmModel nvlist, int cachetimeseconds)
        {
            List<WebResult> bweblist = new List<WebResult>();
            if (!string.IsNullOrEmpty(sign))
            {
                List<AspfmDataSource> Aspfmdatalist = GetDataSource(AbsolutePath);
                if (Aspfmdatalist != null)
                {
                    string[] signlist = sign.Trim().Split(',');
                    foreach (string strsign in signlist)
                    {
                        if (!string.IsNullOrEmpty(strsign.Trim()))
                        {
                            bool hadsign = false;
                            foreach (AspfmDataSource Aspfmds in Aspfmdatalist)
                            {
                                if (Aspfmds.sqlList != null)
                                {
                                    foreach (AspfmDataSql bds in Aspfmds.sqlList)
                                    {
                                        if (strsign.Trim().ToUpper() == (Aspfmds.strKey + "_" + bds.strKey).ToUpper())
                                        {
                                            hadsign = true;
                                            Aspfm.Dal.IDbHelper idb = Aspfm.Dal.DbFactory.GetDB(Aspfmds.strKey);
                                            WebResult bwr = new WebResult();
                                            if (idb == null)
                                            {
                                                bwr.Success = false;
                                                bwr.ErrMsg = "没有找到操作库配置：" + Aspfmds.strKey;
                                                bweblist.Add(bwr);
                                            }
                                            else
                                            {
                                                try
                                                {
                                                    string SqlFiler = nvlist.GetPropertyValueStr(strsign + ".SqlFiler");
                                                    string SqlOrderby = nvlist.GetPropertyValueStr(strsign + ".SqlOrderby");
                                                    bds.SqlStr += " " + SqlFiler.ToString().Trim();
                                                    if (!string.IsNullOrEmpty(SqlOrderby.ToString().Trim()))
                                                    {
                                                        bds.orderby = SqlOrderby.ToString();
                                                    }
                                                    bds.SqlStr = bds.SqlStr.Replace("@参数名称", Aspfmds.strKey + "_" + bds.strKey);
                                                    List<string> strlist = new List<string>();
                                                    string sql = GetFullSql(bds.SqlStr, strlist, nvlist, true);

                                                    string cachesqlkey = string.Empty;
                                                    if (bds.CacheTime <= 0)
                                                    {
                                                        bds.CacheTime = cachetimeseconds;
                                                    }
                                                    if (bds.CacheTime > 0)
                                                    {
                                                        System.Text.StringBuilder cachestr = new System.Text.StringBuilder(sql);
                                                        foreach (string pstr in strlist)
                                                        {
                                                            cachestr.Append(pstr);
                                                        }
                                                        cachesqlkey = cachestr.ToString() + bds.orderby + pageindex + pagesize;
                                                        object webdatasetobj = CacheHelper.GetCache(cachesqlkey);
                                                        if (webdatasetobj != null && webdatasetobj is WebResult)
                                                        {
                                                            bwr = (WebResult)webdatasetobj;
                                                        }
                                                    }
                                                    if (bwr.WebDataSet.Count <= 0)
                                                    {
                                                        if (pagesize > 0 && !string.IsNullOrEmpty(bds.orderby))
                                                        {
                                                            bwr.WebDataSet = WebDataTable.DataSetToWeb(idb.QueryPage(pageindex, pagesize, sql, bds.orderby, strlist.ToArray()));
                                                            bwr.AllCount = idb.QuerySqlCount(sql, strlist.ToArray());
                                                        }
                                                        else
                                                        {
                                                            sql += " " + bds.orderby;
                                                            bwr.WebDataSet = WebDataTable.DataSetToWeb(idb.QuerySql(sql, strlist.ToArray()));
                                                            if (bwr.WebDataSet.Count > 0)
                                                            {
                                                                bwr.AllCount = bwr.WebDataSet[0].Rows.Count;
                                                            }
                                                        }
                                                        if (bds.CacheTime > 0 && (bwr.WebDataSet.Count > 0))
                                                        {
                                                            TimeSpan cachetime = TimeSpan.FromSeconds(bds.CacheTime);
                                                            CacheHelper.SetCache(cachesqlkey, bwr, cachetime);
                                                        }
                                                    }
                                                }
                                                catch (Exception ex)
                                                {
                                                    bwr.Success = false;
                                                    bwr.ErrMsg = ex.Message + ex.StackTrace;
                                                }
                                                bweblist.Add(bwr);
                                            }
                                        }
                                    }
                                }
                            }
                            if (hadsign == false)
                            {
                                WebResult bwr = new WebResult("没有找到：" + strsign + "相关操作。");
                                bweblist.Add(bwr);
                            }
                        }
                    }
                }
                else
                {
                    WebResult bwr = new WebResult("没有找到：" + AbsolutePath + "  相关的Aspfm文件。");
                    bweblist.Add(bwr);
                }
            }
            return bweblist;
        }

        private static List<AspfmDataSource> GetDataSource(string AbsolutePath)
        {
            string datafile = "";
            if (System.IO.File.Exists(AbsolutePath))
            {
                datafile = System.IO.Path.GetDirectoryName(AbsolutePath) + "\\" + System.IO.Path.GetFileNameWithoutExtension(AbsolutePath);
            }
            else
            {
                string path = Aspfm.Dal.DbFactory.CurrentPath();
                datafile = path + System.IO.Path.GetDirectoryName(AbsolutePath)  +"\\" + System.IO.Path.GetFileNameWithoutExtension(AbsolutePath);
                datafile = datafile.Replace("\\\\", "\\");
            }
            List<AspfmDataSource> Aspfmdatalist = AspfmHtml.GetAspfmData(datafile + BaseAshx.Extension);
            return Aspfmdatalist;
        }
        private static string GetFullSql(string sql, List<string> strlist, AspfmModel nvlist, bool isSql = true)
        {
            string pattern = @"\s*【\s*[^\s]*\s*】\s*";
            foreach (Match match in Regex.Matches(sql, pattern))
            {
                string val = match.Value;
                string value = nvlist.GetPropertyValueStr(val.Replace(" ","").TrimStart('【').TrimEnd('】'));
                if (sql.Contains("st(" + val + ")"))
                {
                    sql = sql.Replace("st(" + val + ")", "st(" + strlist.Count.ToString()+ ")");
                    strlist.Add(value);
                }
                else if (sql.Contains("int(" + val + ")"))
                {
                    sql = sql.Replace("int(" + val + ")", "int(" + strlist.Count.ToString() + ")");
                    strlist.Add(value);
                }
                else if (sql.Contains("dt(" + val + ")"))
                {
                    sql = sql.Replace("dt(" + val + ")", "dt(" + strlist.Count.ToString() + ")");
                    strlist.Add(value);
                }
                if (val.StartsWith(" "))
                {
                    sql = sql.Replace(val, " " + Aspfm.Dal.DbFactory.ReplaceDataKeyWord(value));
                }
                else
                {
                    sql = sql.Replace(val,Aspfm.Dal.DbFactory.ReplaceDataKeyWord(value));
                }
            }
            return sql;
        }

        [Description("添加或者修改接口")]
        public static List<WebResult> UpdateSql(string sign, string AbsolutePath, AspfmModel nvlist)
        {
            List<WebResult> bweblist = new List<WebResult>();
            if (!string.IsNullOrEmpty(sign))
            {
                List<AspfmDataSource> Aspfmdatalist = GetDataSource(AbsolutePath);
                if (Aspfmdatalist != null)
                {
                    Dictionary<string, Aspfm.Dal.IDbHelper> Idblist = new Dictionary<string, Aspfm.Dal.IDbHelper>();
                    try
                    {
                        string[] signlist = sign.Trim().Split(',');
                        foreach (string strsign in signlist)
                        {
                            if (!string.IsNullOrEmpty(strsign.Trim()))
                            {
                                bool hadsign = false;
                                foreach (AspfmDataSource Aspfmds in Aspfmdatalist)
                                {
                                    if (Aspfmds.UpdateList != null)
                                    {
                                        foreach (AspfmUpdateSql bds in Aspfmds.UpdateList)
                                        {
                                            if (strsign.Trim().ToUpper() == (Aspfmds.strKey + "_" + bds.strKey).ToUpper())
                                            {
                                                hadsign = true;
                                                Aspfm.Dal.IDbHelper idb = GetIdb(Idblist, Aspfmds.strKey);
                                                UpdateSql(idb, nvlist, bweblist, bds, Aspfmds);
                                            }
                                        }
                                    }
                                    if (Aspfmds.execList != null)
                                    {
                                        foreach (AspfmExecSql bds in Aspfmds.execList)
                                        {
                                            if (strsign.Trim().ToUpper() == (Aspfmds.strKey + "_" + bds.strKey).ToUpper())
                                            {
                                                hadsign = true;
                                                Aspfm.Dal.IDbHelper idb = GetIdb(Idblist, Aspfmds.strKey);
                                                bds.SqlStr = bds.SqlStr.Replace("@参数名称", Aspfmds.strKey + "_" + bds.strKey);
                                                ExecSql(idb, nvlist, bweblist, bds);
                                            }
                                        }
                                    }
                                    if (Aspfmds.procList != null)
                                    {
                                        foreach (AspfmProcSql bds in Aspfmds.procList)
                                        {
                                            if (strsign.Trim().ToUpper() == (Aspfmds.strKey + "_" + bds.strKey).ToUpper())
                                            {
                                                hadsign = true;
                                                bds.SqlStr = bds.SqlStr.Replace("@参数名称", Aspfmds.strKey + "_" + bds.strKey);
                                                ProcSql(Idblist, nvlist, bweblist, Aspfmds, bds);
                                            }
                                        }
                                    }
                                }
                                if (hadsign == false)
                                {
                                    WebResult bwr = new WebResult("没有找到：" + strsign+"相关操作。");
                                    bweblist.Add(bwr);
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        WebResult bwr = new WebResult();
                        bwr.Success = false;
                        bwr.ErrMsg = ex.Message + ex.StackTrace;
                        bweblist.Add(bwr);
                    }
                    finally {
                        bool Success = true;
                        foreach (WebResult webresult in bweblist)
                        {
                            if (webresult.Success == false)
                            {
                                Success = false;
                            }
                        }
                        if (Success)
                        {
                            foreach (Aspfm.Dal.IDbHelper idb in Idblist.Values)
                            {
                                idb.TransactionClose(true);
                            }
                        }
                        else
                        {
                            foreach (Aspfm.Dal.IDbHelper idb in Idblist.Values)
                            {
                                idb.TransactionClose(false);
                            }
                        }
                    }
                }
                else
                {
                    WebResult bwr = new WebResult("没有找到：" + AbsolutePath + "  相关的Aspfm文件。");
                    bweblist.Add(bwr);
                }
            }
            return bweblist;
        }
        private static Aspfm.Dal.IDbHelper GetIdb(Dictionary<string, Aspfm.Dal.IDbHelper> Idblist,string connKey)
        {
            if (Idblist.ContainsKey(connKey))
            {
                return Idblist[connKey];
            }
            Aspfm.Dal.IDbHelper idb = Aspfm.Dal.DbFactory.GetDB(connKey);
            if (idb == null)
            {
                throw new Exception("没有找到数据库连接："+connKey);
            }
            Idblist.Add(connKey,idb);
            idb.TransactionBegin();
            return idb;
        }


        private static void ProcSql(Dictionary<string, Aspfm.Dal.IDbHelper> Idblist, AspfmModel nvlist, List<WebResult> bweblist, AspfmDataSource Aspfmds, AspfmProcSql bds)
        {
            WebResult bwr = new WebResult();
            string[] paramlist = bds.SqlStr.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            if (paramlist != null && paramlist.Length > 0)
            {
                string procname = paramlist[0].Trim();
                if (procname.ToLower().EndsWith(".exe"))
                {
                    if (Idblist.Count > 0)
                    {
                        bds.isWart = false;//如果数据库事务已经启动，就不允许等待EXE程序执行。
                    }
                    Exec(bwr, procname, Aspfmds.strKey, bds.isWart, paramlist, nvlist);
                }
                else
                {
                    Aspfm.Dal.IDbHelper idb = GetIdb(Idblist, Aspfmds.strKey);
                    List<object> strlist = new List<object>();
                    System.Text.StringBuilder sbproccache = new System.Text.StringBuilder(procname.Trim().ToUpper()+".AspfmProc.");
                    for (int i = 1; i < paramlist.Length; i++)
                    {
                        object str = nvlist.GetPropertyValue(paramlist[i].Trim().TrimEnd('】').TrimStart('【'));
                        strlist.Add(str);
                        if (str != null)
                        {
                            sbproccache.Append(str.ToString());
                        }
                    }
                    if (bds.CacheTime > 0)
                    {
                        object webdatasetobj = CacheHelper.GetCache(sbproccache.ToString());
                        if (webdatasetobj != null && webdatasetobj is List<WebDataTable>)
                        {
                            bwr.WebDataSet = (List<WebDataTable>)webdatasetobj;
                        }
                    }
                    if (bwr.WebDataSet.Count <= 0)
                    {
                        bwr.WebDataSet = WebDataTable.DataSetToWeb(idb.ExecProc(procname.Trim().ToUpper(), strlist));
                        if (bds.CacheTime > 0)
                        {
                            TimeSpan cachetime = TimeSpan.FromSeconds(bds.CacheTime);
                            CacheHelper.SetCache(sbproccache.ToString(), bwr.WebDataSet, cachetime);
                        }
                    }
                }
            }
            bweblist.Add(bwr);
        }

        private static void ExecSql(Aspfm.Dal.IDbHelper idb, AspfmModel nvlist, List<WebResult> bweblist, AspfmExecSql bds)
        {
            WebResult bwr = new WebResult();
            List<string> strlist = new List<string>();
            string sql = GetFullSql(bds.SqlStr, strlist, nvlist, true);
            bwr.Success = idb.ExecSql(sql, strlist.ToArray());
            bweblist.Add(bwr);
        }

        private static void UpdateSql(Aspfm.Dal.IDbHelper idb, AspfmModel nvlist, List<WebResult> bweblist, AspfmUpdateSql bds, AspfmDataSource Aspfmds)
        {
            WebResult bwr = new WebResult();
            if (bds.ColList != null)
            {
                AspfmModel dynobj = new AspfmModel();
                foreach (KeyValuePair<string, string> col in bds.ColList)
                {
                    dynobj.Values.Add(col.Key, nvlist.GetPropertyValue("Form."+col.Value));
                }
                string[] collist = bds.columns.Split(',');
                foreach (string colstr in collist)
                {
                    if (!string.IsNullOrEmpty(colstr.Trim()) && !dynobj.Values.ContainsKey(colstr.Trim()))
                    {
                        dynobj.Values.Add(colstr.Trim(), nvlist.GetPropertyValue(Aspfmds.strKey+ "_" + bds.strKey + "." + colstr.Trim()));
                    }
                }
                bwr.Success = idb.SaveData(bds.tablename, dynobj, bds.pkCol, bds.IsInsert);
            }
            bweblist.Add(bwr);
        }
        private static void Exec(WebResult bwr, string procname, string connkey, bool IsWait, string[] paramlist, AspfmModel nvlist)
        {
            string exefile = procname;
            if(!System.IO.File.Exists(exefile))
            {
                exefile = Aspfm.Dal.DbFactory.CurrentPath() + procname;
            }
            if (System.IO.File.Exists(exefile))
            {
                string exeReutrnValueLog = Aspfm.Dal.DbFactory.CurrentPath() + "exeApplication\\exeReutrnValueLog";
                if (!System.IO.Directory.Exists(exeReutrnValueLog))
                {
                    System.IO.Directory.CreateDirectory(exeReutrnValueLog);
                }
                System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(DelYesterdayExeReturnlog), exeReutrnValueLog);
                string logfilename="\\" + Guid.NewGuid().ToString() + ".log";
                string param = "\"" + Aspfm.Dal.DbFactory.CurrentPath().Trim('\\') + "\"" + " \"" + "\\exeApplication\\exeReutrnValueLog" + logfilename + "\"" + " \"" + connkey + "\"";
                exeReutrnValueLog += logfilename;
                Hashtable htparams = new Hashtable();
                for (int i = 1; i < paramlist.Length; i++)
                {
                    string strpatamname = paramlist[i].Trim().TrimEnd('】').TrimStart('【');
                    htparams[strpatamname] = nvlist.GetPropertyValueStr(strpatamname);
                }
                //System.IO.File.AppendAllText(exeReutrnValueLog, sbexeParams.ToString(),System.Text.Encoding.UTF8);
                SerializeHelper.ToFile<Hashtable>(htparams, exeReutrnValueLog);
                Loger.WriteLog("启动exe程序：" + exefile + "    参数：" + param); 
                Process p = Process.Start(exefile, param);
                if (IsWait)
                {
                    try
                    {
                        //让 Process 组件等候相关的进程进入闲置状态。 
                        //p.WaitForInputIdle();
                        //设定要等待相关的进程结束的时间，并且阻止目前的线程执行，直到等候时间耗尽或者进程已经结束为止。 
                        p.WaitForExit();

                        if (p != null)
                        {
                            p.Close();
                            p.Dispose();
                            p = null;
                        }
                        if (File.Exists(exeReutrnValueLog))
                        {
                            try
                            {
                                object objexeReturn = SerializeHelper.FromFile<object>(exeReutrnValueLog);
                                if (objexeReturn is DataSet)
                                {
                                    bwr.WebDataSet = WebDataTable.DataSetToWeb((DataSet)objexeReturn);
                                }
                                else if (objexeReturn is DataTable)
                                {
                                    bwr.WebDataSet.Add(WebDataTable.DataTableToWeb((DataTable)objexeReturn));
                                }
                                else if (objexeReturn is Hashtable)
                                {
                                    bwr.Result = new AspfmModel((Hashtable)objexeReturn);
                                }
                                else
                                {
                                    bwr.Result.SetPropertyValue("exeReturn", objexeReturn);
                                }
                            }
                            catch (Exception ex)
                            {
                                throw ex;
                            }
                            finally
                            {
                                try
                                {
                                    File.Delete(exeReutrnValueLog);
                                }
                                catch { }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        bwr.Success = false;
                        bwr.ErrMsg = ex.Message;
                    }
                }
                else
                {

                }
            }
            else
            {
                bwr.Success = false;
                bwr.ErrMsg = "找不到EXE程序：" + exefile;
            }
        }
        public static void DelYesterdayExeReturnlog(object logpath)
        {
            if (logpath != null && System.IO.Directory.Exists(logpath.ToString()))
            {
                DirectoryInfo folder = new DirectoryInfo(logpath.ToString());
                foreach (FileInfo file in folder.GetFiles("*.log"))
                {
                    DateTime dt = file.CreationTime;
                    if (dt < DateTime.Today)
                    {
                        try
                        {
                            File.Delete(file.FullName);
                        }
                        catch { }
                    }
                }
            }
        }

        public static DataTable GetAspfmDataTable(string connKey, int pageindex, int pagesize, string sql, string SqlOrderby)
        {
            Aspfm.Dal.IDbHelper idb = Aspfm.Dal.DbFactory.GetDB(connKey);
            DataSet ds = idb.QueryPage(pageindex, pagesize, sql, SqlOrderby);
            if (ds != null && ds.Tables.Count > 0)
            {
                return ds.Tables[0];
            }
            return null;
        }
        public static string GetUrlValue(string urlkey)
        {
            string keyvalue = System.Web.HttpContext.Current.Request.QueryString[urlkey];
            if (keyvalue == "undefined")
            { keyvalue = ""; }
            if (!string.IsNullOrEmpty(keyvalue))
            {
                keyvalue = System.Web.HttpUtility.HtmlDecode(keyvalue);
            }
            return keyvalue;
        }
        public static string GetValue(DataTable dttest, int index, string colname, string formatdate = "")
        {
            if (dttest != null && dttest.Rows.Count>index && dttest.Columns.Contains(colname))
            {
                if (dttest.Rows[index][colname] is DateTime && !string.IsNullOrEmpty(formatdate))
                {
                    return ((DateTime)dttest.Rows[index][colname]).ToString(formatdate);
                }
                return dttest.Rows[index][colname].ToString();
            }
            return "";
        }
    }
}
